package estudoregistry.view;

import estudoregistry.control.Pesquisa;
import estudoregistry.model.HiveElement;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class ViewPrincipal extends javax.swing.JFrame {
    private Pesquisa pesquisa;
    private File arquivo;
    private byte[] pagina;
    private HiveElement elemento;
    private Map<String,Integer> mapa;

    public ViewPrincipal() {
        initComponents();
        iniciarListaTipos();
        limparComponentes();
    }

    private void iniciarListaTipos() {
        mapa = new HashMap();
        mapa.put("Desconhecido", HiveElement.UNKNOWN);
        mapa.put("String",HiveElement.STRING);
        mapa.put("Unsigned Integer",HiveElement.UNSIGNED_INTEGER);
        mapa.put( "Offset",HiveElement.OFFSET);
        mapa.put("GUID",HiveElement.GUID);
        mapa.put("Signed Integer",HiveElement.SIGNED_INTEGER);
        mapa.put("Security Descriptor",HiveElement.SECURITY_DESCRIPTOR);
        mapa.put("Flag",HiveElement.FLAG);
        mapa.put("Struture list",HiveElement.STRUCTURE_LIST);
        mapa.put("Regtype Enumeration",HiveElement.REGTYPE_ENUMERATION);
        mapa.put("Raw Data",HiveElement.RAW_DATA);
        mapa.put("Timestamp 64-bits",HiveElement.TIMESTAMP64);

        for (String s:mapa.keySet())jcbTipo.addItem(s);
    }

    private void limparComponentes() {
        desativaPagina();
        desativaElemento();
    }

    private void pesquisaArquivo() {
        setPesquisa(Pesquisa.newInstance(this.getArquivo()));
        ativaPagina();
    }

    private void virarPagina() {
        try {
            this.setPagina(this.getPesquisa().getPagina((Integer)this.jsNumeroPagina.getValue()));
            this.jtfOffset.setText(String.valueOf(this.getPesquisa().getOffsetPagina()));
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, ex.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void exibirElemento() {
        byte[] elemento = new byte[(Integer)this.jsMais.getValue()];
        for (int i=0;i<elemento.length;i++) {
            int indice_relativo = i+Integer.valueOf(this.jtfOffsetCampo.getText());
            elemento[i] = this.getPagina()[indice_relativo];
        }
        setElemento(new HiveElement(elemento));
        this.jtaValor.setText(getElemento().getDataString(this.mapa.get(this.jcbTipo.getSelectedItem())));
    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jfcArquivo = new javax.swing.JFileChooser();
        jbtArquivo = new javax.swing.JButton();
        jtfArquivo = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        jtbTabela = new javax.swing.JTable();
        jpnPagina = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jsNumeroPagina = new javax.swing.JSpinner();
        jLabel2 = new javax.swing.JLabel();
        jtfOffset = new javax.swing.JTextField();
        jbtVirar = new javax.swing.JButton();
        jtbPesquisar = new javax.swing.JButton();
        jpnElemento = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jtfOffsetCampo = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        jsMais = new javax.swing.JSpinner();
        jLabel6 = new javax.swing.JLabel();
        jbtExibir = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        jtaValor = new javax.swing.JTextArea();
        jbtAdicionar = new javax.swing.JButton();
        jLabel7 = new javax.swing.JLabel();
        jcbTipo = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Pesquisa de Hives Registry");

        jbtArquivo.setText("Arquivo:");
        jbtArquivo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtArquivoActionPerformed(evt);
            }
        });

        jtfArquivo.setEditable(false);

        jtbTabela.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null}
            },
            new String [] {
                "Campo", "Tipo", "Dados", "Offset", "Tamanho"
            }
        ));
        jScrollPane1.setViewportView(jtbTabela);

        jpnPagina.setBorder(javax.swing.BorderFactory.createTitledBorder("Página (4096 bytes)"));

        jLabel1.setText("Numero:");

        jsNumeroPagina.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jsNumeroPaginaStateChanged(evt);
            }
        });

        jLabel2.setText("Offset:");

        jtfOffset.setEditable(false);
        jtfOffset.setHorizontalAlignment(javax.swing.JTextField.RIGHT);

        jbtVirar.setText("Virar");
        jbtVirar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtVirarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jpnPaginaLayout = new javax.swing.GroupLayout(jpnPagina);
        jpnPagina.setLayout(jpnPaginaLayout);
        jpnPaginaLayout.setHorizontalGroup(
            jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnPaginaLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jpnPaginaLayout.createSequentialGroup()
                        .addComponent(jsNumeroPagina, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtVirar))
                    .addComponent(jtfOffset, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(489, Short.MAX_VALUE))
        );
        jpnPaginaLayout.setVerticalGroup(
            jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnPaginaLayout.createSequentialGroup()
                .addGroup(jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jsNumeroPagina, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbtVirar))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnPaginaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jtfOffset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jtbPesquisar.setText("Pesquisar");
        jtbPesquisar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jtbPesquisarActionPerformed(evt);
            }
        });

        jpnElemento.setBorder(javax.swing.BorderFactory.createTitledBorder("Elemento"));

        jLabel4.setText("Offset:");

        jtfOffsetCampo.setEditable(false);
        jtfOffsetCampo.setHorizontalAlignment(javax.swing.JTextField.RIGHT);

        jLabel5.setText("mais");

        jLabel6.setText("bytes");

        jbtExibir.setText("Exibir");
        jbtExibir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtExibirActionPerformed(evt);
            }
        });

        jtaValor.setColumns(20);
        jtaValor.setRows(5);
        jScrollPane2.setViewportView(jtaValor);

        jbtAdicionar.setText("Adicionar");

        jLabel7.setText("Tipo:");

        javax.swing.GroupLayout jpnElementoLayout = new javax.swing.GroupLayout(jpnElemento);
        jpnElemento.setLayout(jpnElementoLayout);
        jpnElementoLayout.setHorizontalGroup(
            jpnElementoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnElementoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpnElementoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jpnElementoLayout.createSequentialGroup()
                        .addComponent(jScrollPane2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtAdicionar))
                    .addGroup(jpnElementoLayout.createSequentialGroup()
                        .addComponent(jLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtfOffsetCampo, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jsMais, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jcbTipo, 0, 314, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtExibir)))
                .addContainerGap())
        );
        jpnElementoLayout.setVerticalGroup(
            jpnElementoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnElementoLayout.createSequentialGroup()
                .addGroup(jpnElementoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jtfOffsetCampo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5)
                    .addComponent(jsMais, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)
                    .addComponent(jbtExibir)
                    .addComponent(jLabel7)
                    .addComponent(jcbTipo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnElementoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jbtAdicionar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jpnPagina, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jbtArquivo)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtfArquivo)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtbPesquisar))
                    .addComponent(jpnElemento, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbtArquivo)
                    .addComponent(jtfArquivo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jtbPesquisar))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jpnPagina, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jpnElemento, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jbtArquivoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtArquivoActionPerformed
        if (jfcArquivo.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
            setArquivo(jfcArquivo.getSelectedFile());
        }
    }//GEN-LAST:event_jbtArquivoActionPerformed

    private void jtbPesquisarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtbPesquisarActionPerformed
        pesquisaArquivo();
    }//GEN-LAST:event_jtbPesquisarActionPerformed

    private void jbtVirarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtVirarActionPerformed
        virarPagina();
    }//GEN-LAST:event_jbtVirarActionPerformed

    private void jsNumeroPaginaStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jsNumeroPaginaStateChanged
        if (((Integer)this.jsNumeroPagina.getValue()>0)&&((Integer)this.jsNumeroPagina.getValue()<=this.getPesquisa().getTotalPaginas())) {
            this.jbtVirar.setEnabled(true);
        } else this.jbtVirar.setEnabled(false);
    }//GEN-LAST:event_jsNumeroPaginaStateChanged

    private void jbtExibirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtExibirActionPerformed
        exibirElemento();
    }//GEN-LAST:event_jbtExibirActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ViewPrincipal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ViewPrincipal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ViewPrincipal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ViewPrincipal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ViewPrincipal().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton jbtAdicionar;
    private javax.swing.JButton jbtArquivo;
    private javax.swing.JButton jbtExibir;
    private javax.swing.JButton jbtVirar;
    private javax.swing.JComboBox jcbTipo;
    private javax.swing.JFileChooser jfcArquivo;
    private javax.swing.JPanel jpnElemento;
    private javax.swing.JPanel jpnPagina;
    private javax.swing.JSpinner jsMais;
    private javax.swing.JSpinner jsNumeroPagina;
    private javax.swing.JTextArea jtaValor;
    private javax.swing.JButton jtbPesquisar;
    private javax.swing.JTable jtbTabela;
    private javax.swing.JTextField jtfArquivo;
    private javax.swing.JTextField jtfOffset;
    private javax.swing.JTextField jtfOffsetCampo;
    // End of variables declaration//GEN-END:variables

    private File getArquivo() {
        return arquivo;
    }

    private void setArquivo(File arquivo) {
        this.arquivo = arquivo;
        this.jtfArquivo.setText(this.arquivo.getAbsolutePath());
    }

    private void setPesquisa(Pesquisa pesquisa) {
        this.pesquisa = pesquisa;
    }

    private Pesquisa getPesquisa() {
        return this.pesquisa;
    }

    public byte[] getPagina() {
        return pagina;
    }

    public void setPagina(byte[] pagina) {
        this.pagina = pagina;
        if (this.pagina!=null) {
            ativaElemento();
        }
    }

    private void desativaPagina() {
        desativaNumeroPagina();
        desativaOffsetPagina();        
    }

    private void desativaNumeroPagina() {
        this.jsNumeroPagina.setValue(0);
        this.jsNumeroPagina.setEnabled(false);
        this.jbtVirar.setEnabled(false);
    }

    private void desativaOffsetPagina() {
        this.jtfOffset.setText("");
        this.jtfOffset.setEnabled(false);
    }

    private void desativaElemento() {
        desativaOffsetElemento();
        desativaTipo();
        this.jbtExibir.setEnabled(false);
        desativaValor();
        this.jbtAdicionar.setEnabled(false);
    }

    private void ativaElemento() {
        ativaOffsetElemento();
        ativaTipo();
        jbtExibir.setEnabled(true);
    }

    private void desativaOffsetElemento() {
        this.jtfOffsetCampo.setText("");
        this.jtfOffsetCampo.setEnabled(false);
        this.jsMais.setValue(0);
        this.jsMais.setEnabled(false);
    }

    private void ativaOffsetElemento() {
        this.jtfOffsetCampo.setEnabled(true);
        this.jtfOffsetCampo.setEditable(true);
        this.jsMais.setEnabled(true);
    }

    private void desativaTipo() {
        this.jcbTipo.setSelectedIndex(-1);
        this.jcbTipo.setEnabled(false);
    }

    private void ativaTipo() {
        this.jcbTipo.setEnabled(true);
    }

    private void desativaValor() {
        this.jtaValor.setText("");
        this.jtaValor.setEnabled(false);
    }

    
    private void ativaPagina() {
        ativaNumeroPagina();
        ativaOffsetPagina();
    }

    private void ativaNumeroPagina() {
        this.jsNumeroPagina.setValue(0);
        this.jsNumeroPagina.setEnabled(true);
    }

    private void ativaOffsetPagina() {
        this.jtfOffset.setText("");
        this.jtfOffset.setEnabled(true);
    }

    public HiveElement getElemento() {
        return elemento;
    }

    public void setElemento(HiveElement elemento) {
        this.elemento = elemento;
    }

}
